<?php

/*
$bound_type 	: 
	inbound 	: [order, return, exchange, other]
	outbound 	: [sale, return ,exchange, loss, other]
*/

class Stock_model extends CI_Model
{

	static $TABLE;
	public $error;

	public function __construct()
	{
		parent::__construct();
		//载入库文件
		$this->load->library('test_database');
		$this->test_database->test();
		//载入核心类
		$this->load->database($this->test_database->get_db());
		//载入库文件
		$this->load->library('form_validation');
		//载入帮助函数
		$this->load->helper('date');
		//载入本地语言文件
		$this->lang->load('form_validation','chinese');
		//初始化
		$this->TABLE = 'stocks';
		$this->error = FALSE;
	}

	public function create()
	{
		//var_dump($_POST);
		$this->load->model('Stock_Detail_model');
		$this->load->model('Sub_goods_model');
		$this->load->model('Supplier_model');
		$this->load->model('Suppliers_goods_model');
		$this->load->model('Stock_Advices_model');
		$this->load->model('Inbound_Type_model');
		$this->load->model('Outbound_Type_model');

		$this->Inbound_Type_model->init();
		$this->Inbound_Type_model->get_all('ID_FLG');
		$this->Outbound_Type_model->init();
		$this->Outbound_Type_model->get_all('ID_FLG');

		$stock_type = $this->input->post('stock_type');
		//$bound_type = $this->input->post('stock_bound_type');
		$bound_type_id = $this->input->post('bound_type_id');
		$desc = $this->input->post('description');
		$stock_date = $this->input->post('stock_date');
		$sub_goods_ids = $this->input->post('sub_goods_ids');
		$quantities = $this->input->post('quantities');
		//不一定会提交的值
		$supplier_ids = $this->input->post('supplier_ids');
		$prices = $this->input->post('prices');
		$from_store = $this->input->post('from_store');			//调货时出库仓库
		$to_store = $this->input->post('to_store');				//调货是入库仓库
		$store_type = $this->input->post('store');
		//过滤无效的值
		if(!$supplier_ids)
		{
			unset($supplier_ids);
		}
		if(!$prices)
		{
			unset($prices);
		}

		//检查是否有货品被提交
		if (!$sub_goods_ids)
		{
			$this->error = '请添加货品';
			return;
		}

		//验证表单日期
		$stock_date = explode('-', $stock_date);
		if (3 == count($stock_date) && checkdate($stock_date[1], $stock_date[2], $stock_date[0]))
		{
			$stock_date = mktime(0, 0, 0, $stock_date[1], $stock_date[2], $stock_date[0]);
		}
		else
		{
			$this->error = '不正确的日期格式1';
			return;
		}
		//日期不能小于最后一次结算的日期
		$last_advice_date = $this->Stock_Advices_model->get_advice_date('last');
		if ($last_advice_date)
		{
			$last_advice_year = date('Y', $last_advice_date);
			$last_advice_month = date('m', $last_advice_date);
			$last_advice_date = $last_advice_date + days_in_month($last_advice_month, $last_advice_year) * 24 * 3600 - 1;
			if ($stock_date <= $last_advice_date)
			{
				$this->error = '提交日期不能小于结算月日期：' . date('Y-m-d H:i:s', $last_advice_date);
				return FALSE;
			}
		}

		//判断入库类型的有效性
		if ('inbound' == $stock_type)
		{
			if ($this->Inbound_Type_model->get_one($bound_type_id))
			{
				$bound_type = $this->Inbound_Type_model->inbound_type();
			}
		}
		else if ('outbound' == $stock_type)
		{
			if ($this->Outbound_Type_model->get_one($bound_type_id))
			{
				$bound_type = $this->Outbound_Type_model->outbound_type();
			}
		}
		else if ('transfer' == $stock_type)
		{
			//...
		}

		//检查表单是否有效
		//@items :收集参数
		$count = count($sub_goods_ids);
		if (count($sub_goods_ids) == count($quantities))
		{
			foreach ($sub_goods_ids as $key=>$value)
			{
				//检查数量不能小于1
				if ($quantities[$key] < 1)
				{
					$this->error = '请确认填写的数量都大于0';
					return false;
				}

				//检查是否有重复值
				if (isset($supplier_ids))
				{
					if(isset($item[$sub_goods_ids[$key] . $store_type[$key] . $supplier_ids[$key]]))
					{
						$this->error = '请处理重复项目';
						return false;
					}
					else
					{
						$item[$sub_goods_ids[$key] . $store_type[$key] . $supplier_ids[$key]] = true;
					}
				}
				else if ('transfer' == $stock_type)
				{
					if(isset($item[$sub_goods_ids[$key] . $to_store[$key] . $from_store[$key]]))
					{
						$this->error = '请处理重复项目';
						return false;
					}
					else
					{
						$item[$sub_goods_ids[$key] . $to_store[$key] . $from_store[$key]] = true;
					}
				}
				else
				{
					if(isset($item[$sub_goods_ids[$key] . $store_type[$key]]))
					{
						$this->error = '请处理重复项目';
						return false;
					}
					else
					{
						$item[$sub_goods_ids[$key] . $store_type[$key]] = true;
					}
				}
			}
		}
		else
		{
			//$this->error = '位置错误 LINE ' . __LINE__;
			$this->error = '无效的表单';
			return;
		}

		//判断所选货品的有效性
		if ($sub_goods_ids)
		{
			$sub_goods = $this->Sub_goods_model->get_some($sub_goods_ids);
			if ($this->Sub_goods_model->error)
			{
				$this->error = $this->Sub_goods_model->error;
				return;
			}
		}
		else
		{
			$this->error = '没有添加任何货品！';
			return;
		}

		//判断出库是否超出库存
		//第一次遍历收集必须值
		if ($store_type)
		{
			foreach ($sub_goods_ids as $k=>$v)
			{
				if ('1' == $store_type[$k])
				{
					$sub_goods[$v]->stock -= $quantities[$k];
				}
				else if ('2' == $store_type[$k])
				{
					$sub_goods[$v]->stock_unkown -= $quantities[$k];
				}
				else
				{
					$this->error = 'ERROR:System unkown error on line ' . __LINE__;
					return false;
				}
			}
		}

		//判断是出库、入库、调仓
		if ('inbound' == $stock_type)
		{	
			//判断是否是订货入库，如果是则要检查供应商和货物的一致性和价格有效性
			if ($this->Inbound_Type_model->is_order($bound_type_id))
			{
				$supplier_ids = $this->input->post('supplier_ids');
				$prices = $this->input->post('prices');
				if (count($supplier_ids) == count($sub_goods_ids) && count($prices) == count($sub_goods_ids) )
				{
					foreach ($supplier_ids as $k=>$s)
					{
						if ($prices[$k] < 0)
						{
							$this->error = '价格不能为负数';
							return;
						}
						if (!$this->Suppliers_goods_model->get_one_by_ss($sub_goods_ids[$k], $supplier_ids[$k]))
						{
							$this->error = '存在货品和供应商没有关系的数据！';
							return;
						}
					}				
				}
				else
				{
					$this->error = "供应商出错！";
					return;
				}
			}

			//插入数据
			$data = array(
				'stock_number'	=> date("YmdHis", time()) . substr(time(), -6),
				'stock_user_id'	=> $this->input->cookie('user_id'),
				'stock_realname'=> $this->input->cookie('realname'),
				'stock_type'	=> $stock_type,
				//'stock_bound_type' => $bound_type,
				'bound_type_id'	=> $bound_type_id,
				'stock_date'	=> $stock_date,
				'description'	=> $desc,
				'create_date'	=> time()
				);
			$this->db->insert($this->TABLE, $data);
			if (0 == $this->db->insert_id())
			{
				$this->error = 'ERROR：System Error';
				return;
			}

			//判断是否是进货，传递不同参数
			if ($this->Inbound_Type_model->is_order($bound_type_id))
			{
				$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities, $supplier_ids, $prices);
			}
			else
			{
				$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities);
			}
			
			/***原始版本判断是否是进货，传递不同参数
			switch ($bound_type) {
				case 'order':
					$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities, $supplier_ids, $prices);
					break;
				case 'return':
				case 'exchange':
				case 'other':
					$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities);
					break;
			}
			***/

		}
		else if ('outbound' == $stock_type)
		{
			//判断是否是退货厂家
			if ($this->Outbound_Type_model->is_return($bound_type_id))
			{
				$supplier_ids = $this->input->post('supplier_ids');
				//判断供应商表单有效性
				if (count($supplier_ids) == count($sub_goods_ids) )
				{
					//判断供应商和货品的一致性
					foreach ($supplier_ids as $k=>$s)
					{
						if (!$this->Suppliers_goods_model->get_one_by_ss($sub_goods_ids[$k], $supplier_ids[$k]))
						{
							$this->error = '存在货品和供应商没有关系的数据！';
							return;
						}
					}				
				}
				else
				{
					$this->error = "供应商出错！";
					return;
				}
			}

			//插入数据
			$data = array(
				'stock_number'	=> date("YmdHis", time()) . substr(time(), -6),
				'stock_user_id'	=> $this->input->cookie('user_id'),
				'stock_realname'=> $this->input->cookie('realname'),
				'stock_type'	=> $stock_type,
				//'stock_bound_type' => $bound_type,
				'bound_type_id'	=> $bound_type_id,
				'stock_date'	=> $stock_date,
				'description'	=> $desc,
				'create_date'	=> time()
				);
			$this->db->insert($this->TABLE, $data);
			if (0 == $this->db->insert_id())
			{
				$this->error = 'ERROR：System Error ';
				return;
			}

			//判断是否是退货出库
			if ($this->Outbound_Type_model->is_return($bound_type_id))
			{
				$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities, $supplier_ids);
			}
			else
			{
				$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities);
			}

			/****
			//更新库存详情
			switch ($bound_type) {
				case 'sale':
				case 'other':
				case 'exchange':
				case 'loss':
					$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities);
					break;
				case 'return':
					$this->Stock_Detail_model->create($this->db->insert_id(), $store_type, $stock_type, $bound_type_id, $sub_goods_ids, $quantities, $supplier_ids);
					break;
			}
			****/
		}
		else if ('transfer' == $stock_type)
		{
			//调货方法
			//验证调货仓库有效性
			if (!isset($count))
			{
				$count = count($sub_goods_ids);
			}

			if ($count != count($to_store) || $count != count($from_store))
			{
				$this->error = '提交表单中的仓库出错！';
				return;
			}

			//重新组织仓库编号
			//string: from_store_number|to_store_number
			$stores = array();
			for ($i=0; $i<$count; $i++)
			{
				if (1 != $from_store[$i])
				{
					if (2 != $from_store[$i])
					{
						$this->error = '出仓仓库不存在！';
						return;
					}
				}

				if (1 != $to_store[$i])
				{
					if (2 != $to_store[$i])
					{
						$this->error = '入仓仓库不存在！';
						return;
					}
				}
				
				if ($from_store[$i] == $to_store[$i])
				{
					$this->error = '出库仓库不能和入库仓库相同';
					return;
				}

				$stores[] = $from_store[$i] . '|' . $to_store[$i];
			}

			//更新数据
			$data = array(
				'stock_number'	=> date("YmdHis", time()) . substr(time(), -6),
				'stock_user_id'	=> $this->input->cookie('user_id'),
				'stock_realname'=> $this->input->cookie('realname'),
				'stock_type'	=> $stock_type,
				//'stock_bound_type' => $stock_type,
				'bound_type_id'	=> 0,
				'stock_date'	=> $stock_date,
				'description'	=> $desc,
				'create_date'	=> time()
				);
			$this->db->insert($this->TABLE, $data);
			if (0 == $this->db->insert_id())
			{
				$this->error = 'ERROR：System Error';
				return;
			}
			//重新组织类型
			//调货出库
			$this->Stock_Detail_model->create($this->db->insert_id(), $stores, $stock_type, $bound_type_id, $sub_goods_ids, $quantities);
			unset($count);
		}
		else
		{
			$this->error = '不能判断出入库！';
			return;
		}

		if ($this->Stock_Detail_model->error)
		{
			return $this->error = $this->Stock_Detail_model->error;
		}

	}

	//删除一条库存记录
	public function delete()
	{
		//载入需要的模型
		$this->load->model('Stock_Detail_model');
		$this->load->model('Sub_goods_model');
		$this->load->model('Stock_Advices_model');

		$stock_id = $this->input->post('stock_id');
		if ($stock_id)
		{
			$this->db->where('stock_id', $stock_id);
			$query = $this->db->get($this->TABLE);
			if ($query->num_rows() > 0)
			{
				$result = $query->row();
				//结算过的库存单不能再删除
				if (1 == $result->balance_flg)
				{
					$this->error = 'BALANCED_STOCK';
					return FALSE;
				}
				//已经删除过的订单不能再删除
				else if (1 == $result->del_flg)
				{
					$this->error = 'DELETED_STOCK';
					return FALSE;
				}
				$data = array(
					'del_flg'		=> 1,
					'del_user_id'	=> $this->input->cookie('user_id'),
					'del_realname'	=> $this->input->cookie('realname')
					);
				$this->db->where('stock_id', $stock_id);
				$this->db->update($this->TABLE, $data);
				if ($this->db->affected_rows() > 0)
				{
					$stock_details = $this->Stock_Detail_model->get_detail($stock_id, 'STOCK_ID', 'SINGLE');
					foreach ($stock_details as $detail)
					{
						if (0 == $detail->del_flg)
						{
							if ('inbound' == $detail->stock_type)
							{
								$this->Sub_goods_model->change_stock($detail->sub_goods_id, array($detail->store_id => -$detail->quantity));
							}
							else if ('outbound' == $detail->stock_type)
							{
								$this->Sub_goods_model->change_stock($detail->sub_goods_id, array($detail->store_id => $detail->quantity));
							}

							if ($this->Sub_goods_model->error)
							{
								$this->error = $this->Sub_goods_model->error;
								return FALSE;
							}

							if ( !$this->Stock_Detail_model->custom_query('update', array('stock_id'=>$detail->stock_id), array('del_flg'=>1)) )
							{
								$this->error = 'SET_STOCK_DETAIL_DEL_FAILED';
								return FALSE;
							}
						}
					}
				}
				else
				{
					$this->error = 'NO_CHANGE';
					return FALSE;
				}
			}
			else
			{
				$this->error = 'NO_EXSIT';
				return FALSE;
			}
		}
		else
		{
			$this->error = 'NO_EXSIT';
			return FALSE;
		}

		return TRUE;
	}

	public function get_list($limit, $start, $order_by='timeline', $start_date=FALSE, $end_date=FALSE, $description=FALSE, $stock_type=FALSE, $bound_type_ids=FALSE)
	{
		//载入模型
		$this->load->model('Inbound_Type_model');
		$this->load->model('Outbound_Type_model');
		$this->Inbound_Type_model->init();
		$this->Outbound_Type_model->init();

		//载入帮助函数
		$this->load->helper('check_date_helper');

		$data = array();

		if ($start_date)
		{
			$this->db->where('stock_date >= '.$start_date);
		}
		if ($end_date)
		{
			$this->db->where('stock_date <= '.$end_date);
		}
		if ($description)
		{
			$this->db->like('description', $description);
		}
		if ($stock_type)
		{
			$this->db->where('stock_type', $stock_type);
		}
		if ($bound_type_ids)
		{
			$this->db->where_in('bound_type_id', $bound_type_ids);
		}

		if ('timeline' == $order_by)
		{
			$this->db->order_by('stock_date DESC')->order_by('create_date DESC');
		}
		else
		{
			$this->error = 'ERROR: System!';
		}

		//检查是否出错
		if ($this->error)
		{
			return FALSE;
		}

		$data['count'] = $this->db->count_all_results($this->TABLE);
		if (false !== $data['count'])
		{
			$sql = $this->db->last_query();
			//echo $sql;
			$sql = preg_replace('/^SELECT.*\sFROM\s/', ' SELECT * FROM ', $sql).' LIMIT '.$start.','.$limit;
			if ($query = $this->db->query($sql))
			{
				$data['result'] = $query->result();
				return $data;
			}
		}
		$this->error = 'SYS_ERR|SQL';
		return FALSE;

	}

	public function get_one($stock_id, $get_type='STOCK_ID')
	{

		$this->load->model('Stock_Detail_model');

		$data = array();

		if ('STOCK_ID' == $get_type)
		{
			$this->db->where('stock_id', $stock_id);
			$query = $this->db->get($this->TABLE, 1);
			if (1 == $query->num_rows())
			{
				foreach ($query->result() as $d)
				{
					$data['base'] = $d;
					break;
				}
				$data['detail'] = $this->Stock_Detail_model->get_detail($stock_id, $get_type='STOCK_ID', $return_type='DETAIL', TRUE);
				return $data;
			}
			else
			{
				$this->error = '不存在的出入库单！';
				return FALSE;
			}
		}
		else
		{
			$this->error = 'ERROR: System error[unkown get type:' . $get_type . ']';
			return FALSE;
		}
	}

	//获得时间
	public function get_stock_date($type)
	{
		if ('first' == $type)
		{
			$this->db->order_by('stock_date ASC');
		}
		else if ('last' == $type)
		{
			$this->db->order_by('stock_date DESC');
		}
		$this->db->select('stock_date')->limit(1);
		$query = $this->db->get($this->TABLE);
		if ($query->num_rows() > 0)
		{
			return $query->row()->stock_date;
		}
		else
		{
			$this->error = 'NONE_STOCK';
		}
		return FALSE;
	}

	//获得stock_id
	public function get_stock_ids_by_date($start_date, $end_date=false, $where=array())
	{
		$this->db->select('stock_id');
		if ($end_date)
		{
			$this->db->where('stock_date > '.$start_date.' AND stock_date < '.$end_date);
		}
		else
		{
			$this->db->where('stock_date > '.$start_date);
		}

		if (!empty($where))
		{
			$this->db->where($where);
		}

		$query = $this->db->get($this->TABLE);
		$stock_ids = array();
		foreach ($query->result() as $stock)
		{
			$stock_ids[] = $stock->stock_id;
		}
		return $stock_ids;
	}

	//设置结算标识符
	public function set_balanced($stock_id)
	{
		$where = array(
			'stock_id'	=> $stock_id,
			'balance_flg'	=> '!= 1'
			);
		$this->db->where($where)->limit(1);
		$query = $this->db->get($this->TABLE);
		if (1 == $query->num_rows())
		{
			$set = array(
				'balance_flg'	=> 1
				);
			$where = array(
				'stock_id'	=> $stock_id
				);
			$this->db->set($set)->where($where)->limit(1);
			if ($this->db->update($this->TABLE))
			{
				return TRUE;
			}
			else
			{
				$this->error = 'CANNOT_SET_BALANCED';
			}
		}
		else
		{
			$this->error = 'BALANCED';
		}
		return FALSE;
	}

	//关联结算报表
	public function relate_advice($stock_id, $advice_id)
	{
		$where = array(
			'stock_id'	=> $stock_id
			);
		$set = array(
			'advice_id'	=> $advice_id
			);
		$this->db->set($set)->where($where)->limit(1);
		if ($this->db->update($this->TABLE))
		{
			if (1 == $this->db->affected_rows())
			{
				return TRUE;
			}
			else
			{
				$this->error = 'CANNOT_RELATE_ADVICE';
			}
		}
		else
		{
			$this->error = 'CANNOT_RELATE_ADVICE';
		}
		return FALSE;
	}

	//自定义查询方法
	public function custom_query($type=FALSE, $where=FALSE, $data=FALSE)
	{
		switch ($type) {
			case 'get':
				if ($where)
				{
					$this->db->where($where);
				}
				if ($query = $this->db->get($this->TABLE))
				{
					return $query->result();
				}
				else
				{
					$this->error = 'QUERY_FAILED';
					return FALSE;
				}
				break;

			case 'update':
				if ($where)
				{
					$this->db->where($where);
				}
				else
				{
					$this->error = 'NOT_SET_WHERE';
					return FALSE;
				}
				if ($this->db->update($this->TABLE, $data))
				{
					return TRUE;
				}
				else
				{
					$this->error = 'QUERY_FAILED';
					return FALSE;
				}

			default:
				$this->error = 'NOT_SET_QUERY_TYPE';
				return FALSE;
			break;
		}
	}

}